#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>
#include "unp.h"

#define BUF_SIZE 100
#define MAX_CLNT 256
#define NAME_SIZE 20


void * handle_clnt(void * arg);
void * send_msg(void * arg);
void error_handling(char * msg);

int clnt_cnt=0;
int clnt_socks[MAX_CLNT];
pthread_mutex_t mutx;
void * thread_return;

char msg[BUF_SIZE];

int main(int argc, char *argv[])
{
	int listenfd, connfd;
	struct sockaddr_in servaddr, cliaddr;
	int clilen;
	pthread_t snd_thread, rcv_thread;

	if(argc != 2)
		err_quit("Usage : DataServer_Thread <PortNumber>");

	pthread_mutex_init(&mutx, NULL);
	listenfd = Socket(AF_INET, SOCK_STREAM, 0);

	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port = htons(atoi(argv[1]));

	Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));

	Listen(listenfd, LISTENQ);

	while(1)
	{
		clilen = sizeof(cliaddr);
		connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);

		pthread_mutex_lock(&mutx);
		clnt_socks[clnt_cnt++] = connfd;
		pthread_mutex_unlock(&mutx);

		pthread_create(&snd_thread, NULL, send_msg, (void*)&connfd);
//		pthread_join(snd_thread, &thread_return);
		pthread_detach(snd_thread);
	}
	Close(listenfd);
	return 0;
}

void * handle_clnt(void * arg)
{
	int clnt_sock=*((int*)arg);
	int str_len=0, i;
	char msg[BUF_SIZE];

	pthread_mutex_lock(&mutx);
	for(i=0; i<clnt_cnt; i++)   // remove disconnected client
	{
		if(clnt_sock==clnt_socks[i])
		{
			while(i++<clnt_cnt-1)
				clnt_socks[i]=clnt_socks[i+1];
			break;
		}
	}
	clnt_cnt--;
	pthread_mutex_unlock(&mutx);
	close(clnt_sock);
	return NULL;
}

void * send_msg(void * arg)   // send thread main
{
	int sock=*((int*)arg);
	char name_msg[NAME_SIZE+BUF_SIZE];
	FILE *fp;
	char c;
	int str_len;

	pthread_mutex_lock(&mutx);

	str_len = read(sock, name_msg, NAME_SIZE+BUF_SIZE-1);

	if((fp = fopen(name_msg, "r")) == NULL)
	{
		printf("해당 파일이 존재하지 않거나 기타 문제로 인하여 파일을 요청할 수 없습니다.");
		return 0;
	}

	while(1)
	{
		while(fscanf(fp, "%c", &c) != EOF)
		{
			snprintf(name_msg, sizeof(name_msg), "%c", c);
			write(sock, name_msg, strlen(name_msg));
		}
		printf("Client로 전송을 완료했습니다.\n");
		fclose(fp);
//		exit(0);
	}
	pthread_mutex_lock(&mutx);

	return NULL;
}

void error_handling(char * msg)
{
	fputs(msg, stderr);
	fputc('\n', stderr);
	exit(1);
}
